package com.bugreport.web;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import org.apache.log4j.Logger;
import org.junit.Test;
import org.unitils.UnitilsJUnit4;
import org.unitils.spring.annotation.SpringApplicationContext;
import org.unitils.spring.annotation.SpringBeanByType;

import com.bugreport.model.Issue;
import com.bugreport.test.utils.BugTrackerTestConnector1;
import com.bugreport.test.utils.BugTrackerTestConnector2;
import com.bugreport.utils.BugReportException;

@SpringApplicationContext("com/bugreport/web/ReportIssueControllerTestCase-spring.xml")
public class RICReportIssueTestCase extends UnitilsJUnit4 {

	private static final Logger logger = Logger.getLogger(RICReportIssueTestCase.class);

	@SpringBeanByType
	private ReportIssueController controller;

	@Test
	public void reportIssueFromWwwFooBar() throws BugReportException {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("description");
		issue.setPageUrl("http://www.foo.bar");
		issue.setPageHtmlContent("content");

		// When
		String issueId = controller.reportIssue(issue);

		// Then
		assertNotNull(issueId);
		assertEquals(BugTrackerTestConnector1.ISSUE_ID, issueId);
	}

	@Test
	public void reportIssueFromWwwBarFoo() throws BugReportException {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("description");
		issue.setPageUrl("www.bar.foo");
		issue.setPageHtmlContent("content");

		// When
		String issueId = controller.reportIssue(issue);

		// Then
		assertNotNull(issueId);
		assertEquals(BugTrackerTestConnector2.ISSUE_ID, issueId);
	}

	@Test
	public void reportIssueFromHttpsWwwFooBar() throws BugReportException {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("description");
		issue.setPageUrl("https://www.foo.bar");
		issue.setPageHtmlContent("content");

		// When
		String issueId = controller.reportIssue(issue);

		// Then
		assertNotNull(issueId);
		assertEquals(BugTrackerTestConnector1.ISSUE_ID, issueId);
	}
	
	@Test
	public void failToReportNullIssue() {

		// Given
		Issue issue = null;

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(400, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}

	@Test
	public void failToReportIssueWithoutTitle() {

		// Given
		Issue issue = new Issue();

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(401, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}

	@Test
	public void failToReportIssueWithEmptyTitle() {

		// Given
		Issue issue = new Issue();
		issue.setTitle("   ");

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(401, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}

	@Test
	public void failToReportIssueWithoutDescription() {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(402, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}

	@Test
	public void failToReportIssueWithEmptyDescription() {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("   ");

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(402, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}

	@Test
	public void failToReportIssueWithoutPageUrl() {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("description");

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(403, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}

	@Test
	public void failToReportIssueWithEmptyPageUrl() {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("description");
		issue.setPageUrl("  ");

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(403, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}

	@Test
	public void failToReportIssueWithoutPageHtmlContent() {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("description");
		issue.setPageUrl("www.foo.bar");

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(404, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}
	
	@Test
	public void failToReportIssueWithEmptyPageHtmlContent() {

		// Given
		Issue issue = new Issue();
		issue.setTitle("title");
		issue.setDescription("description");
		issue.setPageUrl("www.foo.bar");
		issue.setPageHtmlContent("   ");

		try {

			// When
			controller.reportIssue(issue);
			fail("Expected exception");

		} catch (BugReportException ex) {

			// Then
			assertNotNull(ex);
			assertEquals(404, ex.getCode());

			logger.debug(ex.getMessage());
		}
	}
}
